<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>策略模式（Strategy Pattern）</title>
    <!-- 
    策略模式（Strategy Pattern）是一种行为型设计模式，它允许在运行时选择算法的行为。策略模式定义了一系列算法，将每一个算法封装起来，并使它们可以互换。该模式使得算法的变化独立于使用算法的客户端。

    ### 策略模式的主要组成部分

    1. **策略接口（Strategy）**：定义了一个公共接口，用于所有支持的算法。
    2. **具体策略（Concrete Strategy）**：实现策略接口，提供具体的算法实现。
    3. **上下文（Context）**：持有一个策略对象的引用，并通过该策略对象调用算法。上下文可以在运行时改变所使用的策略。

    ### 策略模式的优点

    1. **算法的独立性**：策略模式将算法的实现与使用算法的客户端解耦，使得可以独立地更改和扩展算法。
    2. **避免使用大量条件语句**：通过使用策略模式，可以避免在上下文中使用大量的条件语句来选择算法。
    3. **提高代码的可维护性**：当需要增加新的算法时，只需添加新的策略类，而不需要修改现有的代码。

    ### 策略模式的缺点

    1. **增加类的数量**：每个策略都需要一个具体的策略类，可能会导致类的数量增加。
    2. **客户端必须了解所有策略**：客户端需要了解所有可用的策略，以便选择合适的策略。

    ### 示例代码

    以下是一个使用策略模式的简单示例，展示如何实现不同的排序算法。

    #### 1. 策略接口（Strategy）


    ```javascript
    class SortStrategy {
        sort(data) {
            throw new Error("此方法必须被实现。");
        }
    }
    ```


    #### 2. 具体策略（Concrete Strategies）


    ```javascript
    class BubbleSort extends SortStrategy {
        sort(data) {
            console.log("使用冒泡排序");
            // 冒泡排序的实现
            for (let i = 0; i < data.length - 1; i++) {
                for (let j = 0; j < data.length - 1 - i; j++) {
                    if (data[j] > data[j + 1]) {
                        [data[j], data[j + 1]] = [data[j + 1], data[j]];
                    }
                }
            }
            return data;
        }
    }

    class QuickSort extends SortStrategy {
        sort(data) {
            console.log("使用快速排序");
            // 快速排序的实现
            if (data.length <= 1) return data;
            const pivot = data[data.length - 1];
            const left = data.filter(x => x < pivot);
            const right = data.filter(x => x > pivot);
            return [...this.sort(left), pivot, ...this.sort(right)];
        }
    }
    ```


    #### 3. 上下文（Context）


    ```javascript
    class Sorter {
        constructor(strategy) {
            this.strategy = strategy;
        }

        setStrategy(strategy) {
            this.strategy = strategy;
        }

        sort(data) {
            return this.strategy.sort(data);
        }
    }
    ```


    #### 4. 使用示例


    ```javascript
    const data = [5, 3, 8, 1, 2];

    const sorter = new Sorter(new BubbleSort());
    console.log(sorter.sort(data)); // 输出: 使用冒泡排序

    sorter.setStrategy(new QuickSort());
    console.log(sorter.sort(data)); // 输出: 使用快速排序
    ```


    ### 总结

    策略模式是一种灵活且强大的设计模式，适用于需要在运行时选择算法的场景。通过将算法封装为策略对象，策略模式提高了代码的可维护性和可扩展性。在设计系统时，合理运用策略模式可以简化算法的选择逻辑，增强系统的灵活性。
    -->
  </head>
  <body>
    <script>
      // 策略模式是一种行为设计模式，它定义了一系列算法，并将每个算法封装起来，使它们可以互换。策略模式让算法的变化独立于使用算法的客户。
      // 策略模式的主要思想是将算法或行为封装在独立的对象中，使得算法或行为可以在运行时动态地替换。这样，客户端代码就可以根据需要选择不同的算法或行为，而不需要修改客户端代码本身。
      class SortStrategy {
        sort(data) {
          throw new Error("此方法必须被实现。");
        }
      }

      class BubbleSortStrategy extends SortStrategy {
        sort(data) {
          console.log("使用冒泡排序");
        }
      }

      class QuickSortStrategy extends SortStrategy {
        sort(data) {
          console.log("使用快速排序");
        }
      }

      class Sorter {
        constructor(strategy) {
          this.strategy = strategy;
        }

        setStrategy(strategy) {
          this.strategy = strategy;
        }

        sort(data) {
          this.strategy.sort(data);
        }
      }

      const data = [5, 3, 8, 1, 2];
      const sorter = new Sorter(new BubbleSortStrategy());
      sorter.sort(data); // 输出: 使用冒泡排序
      sorter.setStrategy(new QuickSortStrategy());
      sorter.sort(data); // 输出: 使用快速排序
    </script>
  </body>
</html>
